<template>
  <div>
    <!-- 三级联动导航栏 -->
    <el-card>
      <!-- inline:代表的是行内表单，代表一行可以放置多个表单元素 -->
      <el-form :inline="true" class="demo-form-inline" :model="cForm">
        <el-form-item label="一级分类">
          <el-select ref="select1" v-model="cForm.category1Id" placeholder="请选择" @change="handler1($event)" no-data-text="暂无分类数据">
            <el-option v-for="c1 in category1List" :key="c1.cat_id" :label="c1.cat_name" :value="c1.cat_id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="二级分类">
          <el-select ref="select2" v-model="cForm.category2Id" placeholder="请选择" @change="handler2($event)" no-data-text="暂无分类数据" :disabled="!cForm.category1Id">
            <el-option v-for="c2 in category2List" :key="c2.cat_id" :label="c2.cat_name" :value="c2.cat_id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="三级分类">
          <el-select ref="select3" v-model="cForm.category3Id" placeholder="请选择" @change="handler3($event)" no-data-text="暂无分类数据" :disabled="!cForm.category2Id">
            <el-option v-for="c3 in category3List" :key="c3.cat_id" :label="c3.cat_name" :value="c3.cat_id"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 商品信息表格 -->
    <el-card style="margin-top: 20px">
      <el-button type="primary" icon="el-icon-plus" :disabled="!cForm.category3Id" @click="addGoods">添加商品</el-button>
      <el-table :data="goodsList" style="width: 100%; margin-top: 10px" stripe border empty-text="暂无商品数据">
        <el-table-column prop="goods_id" label="商品id" width="80"> </el-table-column>
        <el-table-column prop="goods_name" label="商品名称" width="300"> </el-table-column>
        <el-table-column label="商品图片" width="180">
          <template v-slot="{ row }">
            <el-image style="width: 50px; height: 50px" :src="row.goods_small_logo"></el-image>
          </template>
        </el-table-column>
        <el-table-column label="商品价格" width="180">
          <template v-slot="{ row }">
            <span>{{ row.goods_price.toFixed(2) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="goods_count" label="商品库存" width="180"> </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row }">
            <!-- 商品下架按钮（此时商品处于上架状态） -->
            <el-tooltip v-if="row.is_shelf" class="item" effect="dark" content="下架商品" placement="bottom">
              <el-button type="success" icon="el-icon-bottom" size="mini" @click="updateShelf(row.goods_id, !row.is_shelf)"></el-button>
            </el-tooltip>
            <!-- 商品上架按钮（此时商品处于下架状态） -->
            <el-tooltip v-else class="item" effect="dark" content="上架商品" placement="bottom">
              <el-button type="info" icon="el-icon-top" size="mini" @click="updateShelf(row.goods_id, !row.is_shelf)"></el-button>
            </el-tooltip>
            <!-- 修改商品信息按钮 -->
            <el-tooltip class="item" effect="dark" content="修改商品信息" placement="bottom">
              <el-button type="primary" icon="el-icon-edit" size="mini" @click="updateGoods(row)"> </el-button>
            </el-tooltip>
            <!-- 查看商品详情按钮 -->
            <el-tooltip class="item" effect="dark" content="查看商品详情" placement="bottom">
              <el-button type="info" icon="el-icon-info" size="mini" @click="showGoodsDetail(row)"></el-button>
            </el-tooltip>
            <!-- 删除商品按钮 -->
            <el-tooltip class="item" effect="dark" content="删除商品" placement="bottom">
              <el-popconfirm :title="`确定删除该商品吗?`" @onConfirm="deleteGoods(row.goods_id)" style="margin-left: 10px">
                <el-button slot="reference" type="danger" size="mini" icon="el-icon-delete"></el-button>
              </el-popconfirm>
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 添加商品的dialog弹框 -->
    <el-dialog :title="'添加（' + addGoodsTip + '）分类下的商品'" :visible.sync="showAddDialog" width="50%">
      <el-form ref="addGoodsForm" :model="addForm" label-position="left" :rules="rules">
        <el-form-item label="商品名称" label-width="13%" prop="goods_name">
          <el-input v-model="addForm.goods_name" placeholder="请输入商品名称"></el-input>
        </el-form-item>
        <el-form-item label="商品价格" label-width="13%" prop="goods_price">
          <el-input v-model.number="addForm.goods_price" placeholder="请输入商品价格" width="120"></el-input>
        </el-form-item>
        <el-form-item label="商品库存" label-width="13%" prop="goods_count">
          <el-input-number v-model="addForm.goods_count" :precision="0" :min="1" :max="100"></el-input-number>
        </el-form-item>
        <el-form-item label="商品图片" label-width="13%" prop="goods_small_logo">
          <el-upload class="avatar-uploader" action="#" :http-request="handleUploadLogo" :show-file-list="false" :before-upload="beforeAvatarUpload">
            <img v-if="addForm.goods_small_logo" :src="addForm.goods_small_logo" class="avatar" />
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="* 轮播图" label-width="13%" prop="goods_swiper_img">
          <el-upload class="swiper-uploader" :file-list="addForm.swiperImg" list-type="picture-card" action="#" :http-request="handleUploadSwiper" :before-upload="beforeAvatarUpload" :on-remove="swiperRemove">
            <i class="el-icon-plus swiper-uploader-icon"></i>
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="clearForm">取 消</el-button>
        <el-button type="primary" @click="addGoodsSubmit">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 商品详情抽屉效果 -->
    <el-drawer :visible.sync="showDrawer" :show-close="false" size="40%">
      <el-row>
        <el-col :span="5">商品id</el-col>
        <el-col :span="16">{{ goodsDetail.goods_id }}</el-col>
      </el-row>
      <el-row>
        <el-col :span="5">商品名称</el-col>
        <el-col :span="16">{{ goodsDetail.goods_name }}</el-col>
      </el-row>
      <el-row>
        <el-col :span="5">默认图片</el-col>
        <el-col :span="16">
          <el-image style="width: 100px; height: 100px; border: 1px solid #efefef" :src="goodsDetail.goods_small_logo"></el-image>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="5">商品价格</el-col>
        <el-col :span="16">{{ goodsDetail.goods_price | tofixed }}</el-col>
      </el-row>
      <el-row>
        <el-col :span="5">商品库存</el-col>
        <el-col :span="16">{{ goodsDetail.goods_count }}</el-col>
      </el-row>
      <el-row>
        <el-col :span="5">轮播图</el-col>
        <el-col :span="16">
          <el-carousel height="320px" style="width: 320px; border: 1px solid gray">
            <el-carousel-item v-for="item in goodsSwiper" :key="item.pics_id">
              <img :src="item.pics_big" style="width: 320px; height: auto" />
            </el-carousel-item>
          </el-carousel>
        </el-col>
      </el-row>
    </el-drawer>
    <!-- 修改商品库存的dialog弹框-->
    <el-dialog title="修改商品信息" :visible.sync="showEdit" width="width">
      <el-form :model="updateForm">
        <el-form-item label="商品名称" label-width="13%">
          <el-input v-model="updateForm.goods_name"></el-input>
        </el-form-item>
        <el-form-item label="商品价格" label-width="13%">
          <el-input v-model.number="updateForm.goods_price" width="120"></el-input>
        </el-form-item>
        <el-form-item label="商品库存" label-width="13%">
          <el-input-number v-model="updateForm.goods_count" :precision="0" :min="1" :max="100"></el-input-number>
        </el-form-item>
        <el-form-item label="商品图片" label-width="13%" prop="goods_small_logo">
          <el-upload class="avatar-uploader" action="#" :http-request="updateLogo" :show-file-list="false" :before-upload="beforeAvatarUpload">
            <img :src="updateForm.goods_small_logo" class="avatar" />
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="showEdit = false">取 消</el-button>
        <el-button type="primary" @click="updateGoodsSubmit">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { mapMutations, mapState } from 'vuex'
export default {
  data() {
    // 自定义上传商品轮播图校验规则
    let validateSwiperImg = (rule, value, callback) => {
      if (this.addForm.swiperImg.length === 0) callback(new Error('请上传商品轮播图'))
      else if (this.addForm.swiperImg.length === 1) callback(new Error('至少上传两张商品轮播图'))
      else callback()
    }
    return {
      // 收集一级二级三级分类的id
      cForm: {
        category1Id: '',
        category2Id: '',
        category3Id: ''
      },
      // 控制添加商品dialog弹框的显示与隐藏
      showAddDialog: false,
      // 添加商品表单数据
      addForm: {
        cat_id: '',
        cat_one_id: '',
        cat_two_id: '',
        cat_three_id: '',
        goods_name: '',
        goods_price: '',
        goods_count: 100,
        goods_small_logo: '',
        swiperImg: []
      },
      // 添加商品的dialog弹出框的提示标题
      addGoodsTip: '',
      // 表单验证规则
      rules: {
        goods_name: [{ required: true, message: '请输入商品名称' }],
        goods_price: [
          { required: true, message: '请输入商品价格' },
          { type: 'number', message: '商品价格必须为数字值' }
        ],
        goods_count: [{ required: true, message: '请输入商品库存' }],
        goods_small_logo: [{ required: true, message: '请上传商品图片' }],
        goods_swiper_img: [{ validator: validateSwiperImg }]
      },
      showDrawer: false, // 商品详情el-drawer抽屉的显示与隐藏
      goodsDetail: {}, //商品详情信息
      goodsSwiper: [], // 商品轮播图
      showEdit: false, //控制修改商品信息的显示与隐藏
      // 修改之前的商品信息（用于对比是否对商品进行修改）
      beforeUpdateForm: {
        goods_id: '',
        goods_name: '',
        goods_price: '',
        goods_count: '',
        goods_small_logo: ''
      },
      // 修改商品表单数据
      updateForm: {
        goods_id: '',
        goods_name: '',
        goods_price: '',
        goods_count: '',
        goods_small_logo: ''
      }
    }
  },
  mounted() {
    // 获取一级分类的数据
    this.getCategory1List()
  },
  beforeDestroy() {
    this.clearGoodsList()
  },
  computed: {
    ...mapState('goods', ['category1List', 'category2List', 'category3List', 'goodsList'])
  },
  methods: {
    ...mapMutations('goods', ['getCategory1List', 'getCategory2List', 'getCategory3List', 'clearCategory2List', 'clearCategory3List', 'getGoodsList', 'clearGoodsList']),
    // 一级分类的select事件回调（当一级分类的option发生变化的时候获取相应二级分类的数据）
    handler1(category1Id) {
      this.cForm.category2Id = ''
      this.cForm.category3Id = ''
      this.clearGoodsList()
      this.clearCategory2List()
      this.clearCategory3List()
      this.getCategory2List(category1Id)
    },
    // 二级分类的select事件回调（当二级分类的option发生变化的时候获取相应三级分类的数据）
    handler2(category2Id) {
      this.cForm.category3Id = ''
      this.clearGoodsList()
      this.clearCategory3List()
      this.getCategory3List(category2Id)
    },
    // 三级分类事件的回调
    handler3(category3Id) {
      this.clearGoodsList()
      this.getGoodsList(category3Id)
    },
    // 拼接出添加商品的提示标题
    joinAddGoodsTip() {
      const cat1_id = this.$refs.select1.value
      const cat2_id = this.$refs.select2.value
      const cat3_id = this.$refs.select3.value
      const cat1_name = this.category1List.find(item => item.cat_id === cat1_id).cat_name
      const cat2_name = this.category2List.find(item => item.cat_id === cat2_id).cat_name
      const cat3_name = this.category3List.find(item => item.cat_id === cat3_id).cat_name
      this.addGoodsTip = cat1_name + ' > ' + cat2_name + ' > ' + cat3_name
    },
    // 添加商品
    addGoods() {
      this.joinAddGoodsTip() // 拼接出添加商品的提示标题
      this.addForm.cat_id = this.cForm.category3Id
      this.addForm.cat_one_id = this.cForm.category1Id
      this.addForm.cat_two_id = this.cForm.category2Id
      this.addForm.cat_three_id = this.cForm.category3Id
      this.showAddDialog = true
    },
    // 控制上传图片类型和大小
    beforeAvatarUpload(file) {
      const isJPG = file.type === 'image/jpeg'
      const isPNG = file.type === 'image/png'
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isJPG && !isPNG) {
        this.$message.error('上传分类图片只能是 JPG或PNG 格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传分类图片大小不能超过 2MB!')
      }
      return (isJPG || isPNG) && isLt2M
    },
    // 自定义upload上传商品图片
    handleUploadLogo(data) {
      const file = data.file
      // 使用FileReader对象的readAsDataURL方法来读取图像文件，在Data URL协议中，图片被转换成base64编码的字符串形式
      let reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onloadend = () => (this.addForm.goods_small_logo = reader.result) // 将文件（file）转换成base64字符串
    },
    // 自定义upload上传商品轮播图图片
    handleUploadSwiper(data) {
      const file = data.file
      let reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onloadend = () => this.addForm.swiperImg.push({ url: reader.result })
    },
    // 删除轮播图中某个图片
    swiperRemove(file, fileList) {
      //file是删除的那个图片，fileList是剩余的图片
      this.addForm.swiperImg = this.addForm.swiperImg.filter(item => item.url !== file.url)
    },
    // 添加图片dialog弹框确定按钮处理函数
    addGoodsSubmit() {
      this.$refs.addGoodsForm.validate(async valid => {
        if (valid) {
          // 表单验证通过
          // 添加新商品
          const res = await this.$http({ url: '/api/public/v1/admin/addgoods', data: { newGoods: this.addForm }, method: 'post' })
          if (res.meta.status !== 200) return this.$message.error('添加商品失败')
          this.$message.success(res.meta.msg)
          // 重新获取商品数据
          this.getGoodsList(this.cForm.category3Id)
          // 清除表单
          this.clearForm()
        } else {
          return false
        }
      })
    },
    // 清除表单
    clearForm() {
      this.$refs.addGoodsForm.resetFields()
      this.showAddDialog = false
      this.addForm.swiperImg = []
    },
    // 删除商品
    async deleteGoods(goods_id) {
      const res = await this.$http({ url: '/api/public/v1/admin/deletegoods', data: { goods_id }, method: 'post' })
      if (res.meta.status !== 200) return this.$message.error('删除商品失败')
      this.$message.success('删除商品成功')
      this.getGoodsList(this.cForm.category3Id)
    },
    // 商品详情的按钮处理函数
    async showGoodsDetail(row) {
      const { goods_id } = row
      // 获取轮播图数据
      const res = await this.$http({ url: `/api/public/v1/admin/getgoodsswiper?goods_id=${goods_id}`, method: 'get' })
      if (res.meta.status !== 200) return this.$message.error('获取商品轮播图失败')
      this.goodsSwiper = res.message.goodsSwiper
      this.showDrawer = true
      this.goodsDetail = row
    },
    // 修改商品信息
    updateGoods(row) {
      // 保存修改之前的商品数据
      this.beforeUpdateForm.goods_id = row.goods_id
      this.beforeUpdateForm.goods_name = row.goods_name
      this.beforeUpdateForm.goods_price = row.goods_price
      this.beforeUpdateForm.goods_count = row.goods_count
      this.beforeUpdateForm.goods_small_logo = row.goods_small_logo
      // 初始化（上传到dialog修改弹框）修改商品表单数据
      this.updateForm.goods_id = row.goods_id
      this.updateForm.goods_name = row.goods_name
      this.updateForm.goods_price = row.goods_price
      this.updateForm.goods_count = row.goods_count
      this.updateForm.goods_small_logo = row.goods_small_logo
      this.showEdit = true
    },
    // 修改商品信息dialog弹框确定事件
    async updateGoodsSubmit() {
      let before = this.beforeUpdateForm
      let update = this.updateForm
      if (before.goods_id === update.goods_id && before.goods_name === update.goods_name && before.goods_price === update.goods_price && before.goods_count === update.goods_count && before.goods_small_logo === update.goods_small_logo) return this.$message('未修改商品信息')
      // 修改商品信息
      const res = await this.$http({ url: '/api/public/v1/admin/updategoods', data: { newGoodsInfo: this.updateForm }, method: 'post' })
      if (res.meta.status !== 200) return this.$message.error('修改商品信息失败')
      this.$message.success(res.meta.msg)
      this.showEdit = false
      this.getGoodsList(this.cForm.category3Id)
    },
    // 修改商品图片
    updateLogo(data) {
      const file = data.file
      let reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onloadend = () => (this.updateForm.goods_small_logo = reader.result)
    },
    // 商品上架下架操作
    async updateShelf(goods_id, newShelf) {
      newShelf = newShelf ? 1 : 0
      const errMsg = newShelf === 1 ? '商品上架失败' : '商品下架失败'
      const res = await this.$http({ url: '/api/public/v1/admin/updategoodsshelf', data: { goods_id, newShelf }, method: 'post' })
      if (res.meta.status !== 200) return this.$message.error(errMsg)
      this.$message.success(res.meta.msg)
      this.getGoodsList(this.cForm.category3Id)
    }
  },
  // 过滤器
  filters: {
    // 把数字处理为带两位小数点的数字
    tofixed(num) {
      return Number(num).toFixed(2)
    }
  }
}
</script>

<style lang="scss">
.avatar-uploader {
  width: 120px;
  height: 120px;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;

  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 120px;
    height: 120px;
    line-height: 120px;
    text-align: center;
  }

  .avatar {
    width: 120px;
    height: 120px;
    display: block;
  }
}
.avatar-uploader:hover {
  border-color: #409eff;
}
// 解决el-upload上传多张图片时抖动问题
.el-upload-list__item.is-ready {
  display: none;
}
.el-row .el-col-5 {
  font-size: 18px;
  text-align: right;
}
.el-col {
  margin: 10px 10px;
}
</style>
